package org.huhu.mercury.dal.entity.dao;

import org.hibernate.criterion.DetachedCriteria;
import org.huhu.mercury.common.page.Paged;
import org.huhu.mercury.common.page.PagedResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

/**
 * 带泛型的DAO
 *
 * @param <T>
 * @param <PK>
 * @author luopeng
 */
@Transactional(rollbackFor = Exception.class)
public abstract class ParameterizedBaseDao<T, PK extends Serializable> extends BaseDAO {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    protected Class<T> entityClass;

    public ParameterizedBaseDao(){
        initEntityClass(getClass());
    }

    public T get(PK pk) {
        return this.get(entityClass, pk);
    }

    public T load(PK pk) {
        return load(entityClass, pk);
    }

    public List<T> getAll() {
        return getAll(entityClass);
    }

    public Long getTotalCount() {
        return getTotalCount(entityClass);
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void initEntityClass( Class c){
        Type type = c.getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            Type[] parameterizedType = ((ParameterizedType) type)
                    .getActualTypeArguments();
            this.entityClass = (Class<T>) parameterizedType[0];
        }else{
            initEntityClass((Class)type);
        }
    }
    
	/**
	 * 通过条件分页查询
	 * @param paged
	 * @param paramsMap
	 * @return
	 */
	public PagedResult<T> findPageByParams(Paged paged, Map<String,Object> paramsMap){
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(entityClass);
		assemblePageByParams(detachedCriteria, paramsMap);
		return findByPaged(paged, detachedCriteria);
	}
	
	/**
	 * 重写此方法进行分页
	 * @param detachedCriteria
	 * @param paramsMap
	 */
	public void assemblePageByParams(DetachedCriteria detachedCriteria,Map<String,Object> paramsMap){
		
	}
}